package main

import (
	"context"
	commentserver "hertz_demo/kitex/comment/kitex_gen/commentserver"
	"hertz_demo/orm"
	"hertz_demo/orm/db"

	"gorm.io/gorm"
)

// CommentServiceImpl implements the last service interface defined in the IDL.
type CommentServiceImpl struct{}

// CommentVideo implements the CommentServiceImpl interface.
func (s *CommentServiceImpl) CommentVideo(ctx context.Context, req *commentserver.CommentVideoRequest) (resp *commentserver.CommentVideoResponse, err error) {
	// TODO: Your code here...
	resp = new(commentserver.CommentVideoResponse)
	dbComment := db.Comment{
		UserId:  req.User.ID,
		VideoId: req.VideoId,
		Content: req.Content,
	}
	err = db.DB.Transaction(func(tx *gorm.DB) error {
		if err := tx.Model(&db.Comment{}).Create(&dbComment).Error; err != nil {
			return err
		}
		if err := tx.Model(&db.Video{}).Where("id=?", req.VideoId).Update("comment_count", gorm.Expr("comment_count + ?", 1)).Error; err != nil {
			return err
		}
		return nil
	})
	if err != nil {
		return
	}
	resp.Comment.ID = dbComment.ID
	resp.Comment.Creator = req.User
	resp.Comment.Content = dbComment.Content
	resp.Comment.CreateDate = dbComment.CreatedAt.Format("01-02")
	return
}

// DeleteComment implements the CommentServiceImpl interface.
func (s *CommentServiceImpl) DeleteComment(ctx context.Context, req *commentserver.DeleteCommentRequest) (resp *commentserver.DeleteCommentResponse, err error) {
	// TODO: Your code here...
	resp = new(commentserver.DeleteCommentResponse)
	err = db.DB.Transaction(func(tx *gorm.DB) error {
		commentCnt := 0
		if err := tx.Raw("select count(*) from `comments` where `id`=? and `video_id`=? and `user_id`=?", req.CommentId, req.VideoId, req.User.ID).Scan(&commentCnt).Error; err != nil {
			return err
		}
		if commentCnt == 0 {
			return gorm.ErrRecordNotFound
		}
		if err := tx.Model(&db.Comment{}).Where("id=?", req.CommentId).Update("is_del", true).Error; err != nil {
			return err
		}
		if err := tx.Model(&db.Video{}).Where("id=?", req.VideoId).Update("comment_cnt", gorm.Expr("comment_count - ?", 1)).Error; err != nil {
			return err
		}
		return nil
	})
	return
}

// GetCommentList implements the CommentServiceImpl interface.
func (s *CommentServiceImpl) GetCommentList(ctx context.Context, req *commentserver.GetCommentListRequest) (resp *commentserver.GetCommentListResponse, err error) {
	// TODO: Your code here...
	// var resultList []models.Comment
	resp = new(commentserver.GetCommentListResponse)
	var followList []int64
	if err = db.DB.Model(&db.FollowRelation{}).Select("follow_user_id").Where("user_id=?", req.UserId).Find(&followList).Error; err != nil {
		return
	}
	var dbCommentList []db.Comment
	if err = db.DB.Model(&db.Comment{}).Where("`video_id`=? and `is_del`=0", req.VideoId).Find(&dbCommentList).Error; err != nil {
		return
	}
	var commentUserIdList []int64
	for _, dbComment := range dbCommentList {
		commentUserIdList = append(commentUserIdList, dbComment.UserId)
	}
	followList = orm.GetIntersection(followList, commentUserIdList)
	var dbUserList []db.User
	if err = db.DB.Model(&db.User{}).Find(&dbUserList, commentUserIdList).Error; err != nil {
		return
	}
	for _, dbComment := range dbCommentList {
		isFollow := false
		for _, id := range followList {
			if id == dbComment.UserId {
				isFollow = true
				break
			}
		}
		commentUser := commentserver.User{
			ID:       dbComment.UserId,
			IsFollow: isFollow,
		}
		for _, dbUser := range dbUserList {
			if dbUser.ID == dbComment.UserId {
				commentUser.Name = dbUser.Name
				commentUser.FollowCount = dbUser.FollowCount
				commentUser.FollowerCount = dbUser.FollowerCount
				break
			}
		}
		comment := commentserver.Comment{
			ID:         dbComment.ID,
			Creator:    &commentUser,
			Content:    dbComment.Content,
			CreateDate: dbComment.CreatedAt.Format("01-02"),
		}
		resp.ResultList = append(resp.ResultList, &comment)
	}
	return
}
